package com.flute.tools.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class DateUtil {
	public enum TimeUnit {
		day, month, week, hour, minute, second
	}

	public static String getDateString(Date date) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		return formatter.format(date);
	}

	public static String getTimeString(Date date) {
		SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
		return formatter.format(date);
	}

	public static String getDateAndTimeString(Date date) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return formatter.format(date);
	}

	public static Date getDateFromString(String date) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			return new Date(formatter.parse(date).getTime());
		} catch (ParseException e) {
		}

		return null;
	}

	public static double getTimeByMinute(Date date1, Date date2) {
		return Math.abs((date1.getTime() - date2.getTime()))
				/ Double.valueOf("60000");
	}

	public static double getTimeBySecond(Date date1, Date date2) {
		return Math.abs((date1.getTime() - date2.getTime()))
				/ Double.valueOf("1000");
	}

	public static double getTimeByHour(Date date1, Date date2) {
		return Math.abs((date1.getTime() - date2.getTime()))
				/ Double.valueOf("3600000");
	}

	public static double getTimeByDay(Date date1, Date date2) {
		return Math.abs((date1.getTime() - date2.getTime()))
				/ Double.valueOf("86400000");
	}

	public static double getTimeByWeek(Date date1, Date date2) {
		return Math.abs((date1.getTime() - date2.getTime()))
				/ Double.valueOf("604800000");
	}

	public static double getTimeByMonth(Date date1, Date date2) {
		return Math.abs((date1.getTime() - date2.getTime()))
				/ Double.valueOf("2592000000");
	}

	public static double getTimeValue(TimeUnit tu, Date date1, Date date2) {
		switch (tu) {
		case day:
			return getTimeByDay(date1, date2);
		case month:
			return getTimeByMonth(date1, date2);
		case week:
			return getTimeByWeek(date1, date2);
		case hour:
			return getTimeByHour(date1, date2);
		case minute:
			return getTimeByMinute(date1, date2);
		case second:
			return getTimeBySecond(date1, date2);
		default:
			return 0;
		}
	}

	public static long getMiniseconds(TimeUnit tu, double value) {
		Double d;
		switch (tu) {
		case day:
			d = Long.valueOf("86400000") * value;
			break;
		case month:
			d = Long.valueOf("2592000000") * value;
			break;
		case week:
			d = Long.valueOf("604800000") * value;
			break;
		case hour:
			d = Long.valueOf("3600000") * value;
			break;
		case minute:
			d = Long.valueOf("60000") * value;
			break;
		case second:
			d = Long.valueOf("1000") * value;
			break;
		default:
			d = Double.valueOf(0);
			break;
		}

		return d.longValue();
	}

	public static Date getBeforeDay(TimeUnit tu, double value) {
		Double time = Double.valueOf(1);
		switch (tu) {
		case day:
			time = value * Double.valueOf(86400000);
			break;
		case month:
			time = value * Double.valueOf("2592000000");
			break;
		case week:
			time = value * Double.valueOf(604800000);
			break;
		case hour:
			time = value * Double.valueOf(3600000);
			break;
		case minute:
			time = value * Double.valueOf(60000);
		case second:
			time = value * Double.valueOf(1000);
			break;
		}

		return new Date(new Date().getTime() - time.longValue());
	}

	public static int getDateCount(TimeUnit tu, int value) {
		switch (tu) {
		case day:
			return value * 1;
		case month:
			return value * 30;
		case week:
			return value * 7;
		}

		return 1;
	}

	public static Date getClosestDate(Date date, List<Date> list) {
		long min = Long.MAX_VALUE;
		Date result = null;
		for (Date d : list) {
			long value = Math.abs(date.getTime() - d.getTime());
			if (min > value) {
				min = value;
				result = d;
			}
		}

		if (list.size() > 0 && result.getTime() < list.get(0).getTime()) {
			result = null;
		}

		return result;
	}

	public static List<Date> getDateList(TimeUnit tu, int value,
			int displayCount, Date earliestDay) {
		Double count = Math.min(Double.valueOf(getDateCount(tu, value)),
				getTimeValue(TimeUnit.day, new Date(), earliestDay));
		double fre = count / Double.valueOf(displayCount);
		if (fre < 1) {
			displayCount = count.intValue();
			fre = Double.valueOf(1);
		}
		List<Date> list = new ArrayList<Date>();
		for (int i = 1; i < displayCount + 1; i++) {
			list.add(getBeforeDay(TimeUnit.day, Double
					.valueOf((displayCount - i))
					* fre));
		}

		return list;
	}

	public static boolean isBetweenTime(String start, String end) {
		String now = getTimeString(new Date());
		return now.compareTo(start) > 0 && now.compareTo(end) < 0;
	}

	public static String getDayByToday(int count) {
		Date date = new Date();// 取时间
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动
		date = calendar.getTime(); // 这个时间就是日期往后推一天的结果
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = formatter.format(date);

		return dateString;
	}

	public static Date getDateByTodayWithTime(int count, String time) {
		Date date = new Date();// 取时间
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动
		date = calendar.getTime(); // 这个时间就是日期往后推一天的结果
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = formatter.format(date);

		return getDateFromString(dateString + " " + time);
	}
}